package com.boolib.service.impl;

import com.boolib.bo.RedisCartBo;

import com.boolib.commons.Const;
import com.boolib.commons.entity.ServerResponse;
import com.boolib.commons.util.BigDecimalUtil;
import com.boolib.dao.ShopProductMapper;
import com.boolib.dao.ShopSkuMapper;
import com.boolib.dao.ShopUserMapper;
import com.boolib.pojo.ShopProduct;
import com.boolib.pojo.ShopSku;
import com.boolib.pojo.ShopUser;
import com.boolib.service.ICartService;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class CartServiceImpl implements ICartService {



    @Autowired
    private ShopUserMapper shopUserMapper;


    @Resource
    RedisTemplate redisTemplate;


    @Autowired
    private ShopProductMapper shopProductMapper;

    @Autowired
    private ShopSkuMapper shopSkuMapper;



    @Override
    public ServerResponse queryByUserId(Integer userId) {

        String pre = Const.Cart.REDIS_PERFIX+userId;

        Set<Integer> keys =  redisTemplate.opsForHash().keys(pre);

        Map map = Maps.newLinkedHashMap();

        for (Integer skuId: keys) {
            map.put(skuId,(RedisCartBo)redisTemplate.opsForHash().get(pre,skuId));
        }
        return  ServerResponse.createBySuccess(map);
    }


    /**
     *
     * 添加
     * @param userId
     * @param redisCartBo

     * @return
     */

    @Override
    public ServerResponse add(Integer userId, RedisCartBo redisCartBo ) {
        Integer quantity =redisCartBo.getQuantity();
        String pre = Const.Cart.REDIS_PERFIX+userId;

        /**
         * 判断用户状态是否正常
         */
        ShopUser shopUser = new ShopUser();

        shopUser.setStatus(Const.User.NORMAL);

        shopUser.setId(userId);


        ShopUser dbResult = shopUserMapper.selectOne(shopUser);

        if(dbResult == null) return  ServerResponse.createByError(Const.User.Status.USERNOTEXIST.getCode()
        , Const.User.Status.USERNOTEXIST.getMessage() );


        /**
         * 判断商品是否存在，并且状态正常
         */


        ShopProduct shopProduct = new ShopProduct();

        shopProduct.setStatus(Const.Product.NORMAL);

        shopProduct.setId(redisCartBo.getSpuId());

        ShopProduct dbResultProduct = shopProductMapper.selectOne(shopProduct);

        if(dbResultProduct == null) return ServerResponse.createByError(Const.Product.Status.OFF_SALE.getCode(),
                Const.Product.Status.OFF_SALE.getMessage());


        /**
         * 判断sku商品 是否存在
         */



        ShopSku shopSku = new ShopSku();


        shopSku.setStatus(Const.System.GLOBAL_NORMAL);

        shopSku.setId(redisCartBo.getSkuId());


        ShopSku dbResultShopSku = shopSkuMapper.selectOne(shopSku);


        if(dbResultShopSku == null ) return ServerResponse.createByError(Const.Product.Status.OFF_SALE.getCode(),
                Const.Product.Status.OFF_SALE.getMessage());



        /**
         * 判断库存剩余
         */


        Integer count = 0 ;


        count = dbResultShopSku.getSkuStock();


        /**
         * 判断购物车里是否有该商品
         */

       RedisCartBo redisCartBo2 =  (RedisCartBo)redisTemplate.opsForHash().get(pre,redisCartBo.getSkuId());


       //如果不存在则插入
       if(redisCartBo2 == null ){

           RedisCartBo temp = new RedisCartBo();

           temp.setSpuId(dbResultProduct.getId());
           temp.setChecked(Const.Cart.UNCHECK);

           temp.setImg(dbResultShopSku.getSkuImg());

           temp.setPrice(dbResultShopSku.getSkuPrice());


           if(count<quantity){
               quantity = count;
           }


           temp.setQuantity(quantity);


           temp.setTitle(dbResultProduct.getProductTitle());

           temp.setSkuId(dbResultShopSku.getId());

           temp.setTotalPrice(BigDecimalUtil.mul(temp.getPrice().doubleValue(),quantity));

           redisTemplate.opsForHash().put(pre,dbResultShopSku.getId(),temp);

       }
        else{

           //如果购物车 当前商品存在

           //获取购物车数量
           Integer redisQuantity =  redisCartBo2.getQuantity();
           // Redis中数量 与新添加商品数量 相加
           redisQuantity +=quantity;

           //核对库存
           if(count<redisQuantity){
               redisQuantity = count;
           }

           //更新最新商品价格
           redisCartBo2.setPrice( dbResultShopSku.getSkuPrice());

           //更新商品数量
           redisCartBo2.setQuantity(redisQuantity);

           //更新总价
           redisCartBo2.setTotalPrice(BigDecimalUtil.mul(redisCartBo2.getPrice().doubleValue(),redisQuantity));

           redisTemplate.opsForHash().put(pre,dbResultShopSku.getId(),redisCartBo2);

       }


        return  queryByUserId(userId);
    }


    /**
     * 购物车减少
     * @param userId
     * @param redisCartBo
     * @param
     * @return
     */
    @Override
    public ServerResponse sub(Integer userId, RedisCartBo redisCartBo) {
        Integer quantity =redisCartBo.getQuantity();
        String pre = Const.Cart.REDIS_PERFIX+userId;

        /**
         * 判断用户状态是否正常
         */
        ShopUser shopUser = new ShopUser();

        shopUser.setStatus(Const.User.NORMAL);

        shopUser.setId(userId);


        ShopUser dbResult = shopUserMapper.selectOne(shopUser);

        if(dbResult == null) return  ServerResponse.createByError(Const.User.Status.USERNOTEXIST.getCode()
                , Const.User.Status.USERNOTEXIST.getMessage() );


        /**
         * 判断商品是否存在，并且状态正常
         */


        ShopProduct shopProduct = new ShopProduct();

        shopProduct.setStatus(Const.Product.NORMAL);

        shopProduct.setId(redisCartBo.getSpuId());

        ShopProduct dbResultProduct = shopProductMapper.selectOne(shopProduct);

        if(dbResultProduct == null) return ServerResponse.createByError(Const.Product.Status.OFF_SALE.getCode(),
                Const.Product.Status.OFF_SALE.getMessage());


        /**
         * 判断sku商品 是否存在
         */



        ShopSku shopSku = new ShopSku();


        shopSku.setStatus(Const.Product.NORMAL);

        shopSku.setId(redisCartBo.getSkuId());


        ShopSku dbResultShopSku = shopSkuMapper.selectOne(shopSku);


        //todo
        if(dbResultShopSku == null ) return ServerResponse.createByError(Const.Product.Status.OFF_SALE.getCode(),
                Const.Product.Status.OFF_SALE.getMessage());



        /**
         * 判断库存剩余
         */


        Integer count = 0 ;


        count = dbResultShopSku.getSkuStock();


        /**
         * 判断购物车里是否有该商品
         */

        RedisCartBo redisCartBo2 =  (RedisCartBo)redisTemplate.opsForHash().get(pre,redisCartBo.getSkuId());


        //如果不存在则插入
        if(redisCartBo2 == null ) {

            return ServerResponse.createByError(Const.Cart.CartStatusEnum.UNEXIST.getCode(), Const.Cart.CartStatusEnum.UNEXIST.getMessage() );
        }else{

            //如果购物车 当前商品存在

            //获取购物车数量
            Integer redisQuantity =  redisCartBo2.getQuantity();
            // Redis中数量 与新添加商品数量 相加
            redisQuantity -=quantity;

            //核对库存
            if(redisQuantity<0){
                redisQuantity = 0;
            }

            //更新最新商品价格
            redisCartBo2.setPrice( dbResultShopSku.getSkuPrice());

            //更新商品数量
            redisCartBo2.setQuantity(redisQuantity);

            //更新总价
            redisCartBo2.setTotalPrice(BigDecimalUtil.mul(redisCartBo2.getPrice().doubleValue(),redisQuantity));

            redisTemplate.opsForHash().put(pre,dbResultShopSku.getId(),redisCartBo2);

        }


        return  queryByUserId(userId);
    }




    @Override
    public ServerResponse removeOne(Integer userId, Integer skuId) {

        String pre = Const.Cart.REDIS_PERFIX + userId;

        /**
         * 判断用户状态是否正常
         */
        ShopUser shopUser = new ShopUser();

        shopUser.setStatus(Const.User.NORMAL);

        shopUser.setId(userId);


        ShopUser dbResult = shopUserMapper.selectOne(shopUser);

        if (dbResult == null) return ServerResponse.createByError(Const.User.Status.USERNOTEXIST.getCode()
                , Const.User.Status.USERNOTEXIST.getMessage());


        RedisCartBo redisCartBo = (RedisCartBo) redisTemplate.opsForHash().get(pre,skuId);

        if(redisCartBo != null) {
            long l =redisTemplate.opsForHash().delete(pre,skuId);
        }


        return queryByUserId(userId);

    }

    @Override
    public ServerResponse removeAll(Integer userId) {

        String pre = Const.Cart.REDIS_PERFIX + userId;

        /**
         * 判断用户状态是否正常
         */
        ShopUser shopUser = new ShopUser();

        shopUser.setStatus(Const.User.NORMAL);

        shopUser.setId(userId);


        ShopUser dbResult = shopUserMapper.selectOne(shopUser);

        if (dbResult == null) return ServerResponse.createByError(Const.User.Status.USERNOTEXIST.getCode()
                , Const.User.Status.USERNOTEXIST.getMessage());


        redisTemplate.expire(pre,1,TimeUnit.SECONDS);

        return  queryByUserId(userId);
    }







}
